home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d11 / egafast.arc / EGAFAST2 < prev    next >
Encoding:
Text File  |  1988-04-17  |  31.3 KB  |  997 lines

  1. Path: marob!mancol!manhat!phri!cmcl2!nrl-cmf!ames!necntc!ncoast!allbery
  2. From: mcdonald@uxe.cso.uiuc.edu (J.D. McDonald )
  3. Newsgroups: comp.sources.misc
  4. Subject: v02i023: EGAFAST IBM-PC Graphics Package, Part 2/2
  5. Message-ID: <7134@ncoast.UUCP>
  6. Date: 26 Jan 88 04:30:40 GMT
  7. Sender: allbery@ncoast.UUCP
  8. Lines: 982
  9. Approved: allbery@ncoast.UUCP
  10. X-Archive: comp.sources.misc/egafast/2
  11. Comp.sources.misc: Volume 2, Issue 23
  12. Submitted-By: J.D. McDonald <mcdonald@uxe.cso.uiuc.edu>
  13. Archive-Name: egafast/Part2
  14.  
  15. Comp.sources.misc: Volume 2, Issue 23
  16. Submitted-By: J.D. McDonald <mcdonald@uxe.cso.uiuc.edu>
  17. Archive-Name: egafast/Part2
  18.  
  19. due to the size, distribution is in two parts 
  20. This is part 2.
  21.  
  22. *********begin second copy of READ.ME*************
  23. This is a very simple graphics package for the EGA and VGA. It draws the
  24. basic primitives of lines, ellipses, filled rectangles, filled ellipses,
  25. and text (two sizes and user defined). It is written to get the ultimate
  26. in high speed possible while drawing in the set/reset mode. It can be
  27. called from Microsoft C and Fortran, or any language including assembler
  28. which follows their calling conventions.
  29. Here is a list of the included files:
  30.  
  31. CLIPLINE C     Source code for clipped line routine.
  32. EGAFORT  H     Header file for subroutine prototypes for Fortran.
  33. EGAGRA   ASM   The main graphics package source.
  34. EGAGRA   DOC   Documentation.
  35. EGATEST  C     A test program to verify correct compilation.
  36. ELLIPSE  C     Source code for ellipse drawers.
  37. GRAFEX1  C     Example program that draws a star.
  38. GRAFEX2  C     Example program that uses user-defined patterns.
  39. INTEST   ASM   Assembler subroutine for SLUGS.FOR
  40. MACROS   AH    Header file for EGAGRA.ASM which defines memory model.
  41. MOVERM   C     Example program for plane masking.
  42. MOVERS   C     Example program for page swapping and plane masking.
  43. SLUGS    FOR   Example program in Fortran whose results look nice.
  44.  
  45. Some of the code in this package is patterned after that of U.E.Kruse of
  46. the U. of I. Physics department. The grafex1 demo program generates
  47. essentially the same pattern as the one of the same name in the package
  48. by Scott Snyder of caltech recently posted on the net. The macros.ah
  49. is also from his package.
  50.  
  51. Your comments are welcome, especially if you see anything faster.
  52.  
  53. Doug McDonald
  54. University of Illinois
  55. 505 S. Matthews 
  56. Urbana Ill. 61801
  57. (mcdonald@uiucuxe or mcdonald@uxe.cso.uiuc.edu)
  58.  
  59.  
  60. ***********end second copy of READ.ME***********
  61. ***********begin file ELLIPSE.C*****************
  62. /* Draw an ellipse with width irx and height iry                         */
  63. /* from a routine by Tim Hogan in Dr. Dobb's Journal May '85 p.40        */
  64. /* Improved by calculating increments incrementally, thus removing all   */
  65. /* multiplies from the loops. These multiplies were very bad since they  */
  66. /* were (long)*(long). This code, when compiled by Microsoft C Version 4,*/
  67. /* can't be significantly improved by hand optimization.                 */
  68. /* Written Sept. 7, 1987 by J.D. McDonald (public domain)                */
  69.  
  70. static long     alpha, beta, alpha2, alpha4, beta2, beta4, d;
  71. static long     ddx, ddy, alphadx, betady;
  72. static int      dy, dx;
  73.  
  74. extern void     e_start();    /* Starts off by writing right and left
  75.                  * points                                */
  76. extern void     e_xd();    /* Moves one step to lower x (in all 4 quadrants)*/
  77. extern void     e_xdyu();    /* Moves to lower x, higher y            */
  78. extern void     e_yu();       /* Moves to higher y                     */
  79.  
  80. ellipse(x, y, irx, iry, c)
  81.     int             x, y, irx, iry;
  82.     unsigned        c;
  83. {
  84.  
  85.     beta = (long) irx *(long) irx;
  86.     alpha = (long) iry *(long) iry;
  87.  
  88.     if (alpha == 0L)
  89.     alpha = 1L;
  90.     if (beta == 0L)
  91.     beta = 1L;
  92.  
  93.     dy = 0;
  94.     dx = irx;
  95.     alpha2 = alpha << 1;
  96.     alpha4 = alpha2 << 1;
  97.     beta2 = beta << 1;
  98.     beta4 = beta2 << 1;
  99.     alphadx = alpha * dx;
  100.     betady = 0;
  101.     ddx = alpha4 * (1 - dx);
  102.     ddy = beta2 * 3;
  103.  
  104.     d = alpha2 * ((long) (dx - 1) * dx) + alpha + beta2 * (1 - alpha);
  105.     e_start(x - dx, x + dx, y, c);
  106.  
  107.     do {
  108.     if (d >= 0) {
  109.         d += ddx;
  110.         dx--;
  111.         alphadx -= alpha;
  112.         ddx += alpha4;
  113.         e_xdyu();
  114.     } else
  115.         e_yu();
  116.     d += ddy;
  117.     dy++;
  118.     betady += beta;
  119.     ddy += beta4;
  120.     } while (alphadx > betady);
  121.  
  122.     d = beta2 * ((long) dy * (dy + 1)) + alpha2 * ((long) dx * (dx - 2) + 1) 
  123.     + beta * (1 - alpha2);
  124.     ddx = alpha2 * (3 - (dx << 1));
  125.     ddy = beta4 * (1 + dy);
  126.  
  127.     do {
  128.     if (d <= 0) {
  129.         d += ddy;
  130.         ddy += beta4;
  131.         dy++;
  132.         e_xdyu();
  133.     } else
  134.         e_xd();
  135.     d += ddx;
  136.     ddx += alpha4;
  137.     dx--;
  138.     } while (dx > 0);
  139. }
  140.  
  141. fillelip(x, y, irx, iry, c)
  142.     int             x, y, irx, iry;
  143.     unsigned        c;
  144. {
  145.  
  146.     beta = (long) irx *(long) irx;
  147.     alpha = (long) iry *(long) iry;
  148.  
  149.     if (alpha == 0L)
  150.     alpha = 1L;
  151.     if (beta == 0L)
  152.     beta = 1L;
  153.  
  154.     dy = 0;
  155.     dx = irx;
  156.     alpha2 = alpha << 1;
  157.     alpha4 = alpha2 << 1;
  158.     beta2 = beta << 1;
  159.     beta4 = beta2 << 1;
  160.     alphadx = alpha * dx;
  161.     betady = 0;
  162.     ddx = alpha4 * (1 - dx);
  163.     ddy = beta2 * 3;
  164.  
  165.     d = alpha2 * ((long) (dx - 1) * dx) + alpha + beta2 * (1 - alpha);
  166.     rectfill(x - dx, y, x + dx, y, c);
  167.  
  168.     do {
  169.     if (d >= 0) {
  170.         d += ddx;
  171.         dx--;
  172.         alphadx -= alpha;
  173.         ddx += alpha4;
  174.     }
  175.     d += ddy;
  176.     dy++;
  177.     betady += beta;
  178.     ddy += beta4;
  179.     rectfill(x - dx, y + dy, x + dx, y + dy, c);
  180.     rectfill(x - dx, y - dy, x + dx, y - dy, c);
  181.     } while (alphadx > betady);
  182.  
  183.     d = beta2 * ((long) dy * (dy + 1)) + alpha2 * ((long) dx * (dx - 2) + 1) 
  184.     + beta * (1 - alpha2);
  185.     ddx = alpha2 * (3 - (dx << 1));
  186.     ddy = beta4 * (1 + dy);
  187.  
  188.     do {
  189.     dx--;
  190.     if (d <= 0) {
  191.         d += ddy;
  192.         ddy += beta4;
  193.         dy++;
  194.         rectfill(x - dx, y + dy, x + dx, y + dy, c);
  195.         rectfill(x - dx, y - dy, x + dx, y - dy, c);
  196.     }
  197.     d += ddx;
  198.     ddx += alpha4;
  199.     } while (dx > 0);
  200. }
  201.  
  202. ***********end file ELLIPSE.C*******************
  203. ***********begin file CLIPLINE.C****************
  204. /*routine to plot clipped line*/
  205. clipline(x1,y1,x2,y2,icol)
  206. int x1,y1,x2,y2,icol;
  207. {
  208.     int x3, y3, x4, y4;
  209.     if(clip_ln(x1,y1,&x3,&y3,x2,y2)){
  210.       if(clip_ln(x2,y2,&x4,&y4,x3,y3))
  211.          zline(x4,y4,x3,y3,icol);
  212.     }
  213. }
  214.  
  215. /* routine to clip one endpoint of a line */
  216. /* to clip to a rectangle instead of the screen, change MINX, MAXX, and MINY
  217.    to input parameters instead of defines, and fix maxy also */
  218. #define MINY 0
  219. #define MINX 0
  220. #define MAXX 639
  221. extern int max_lin(void);
  222. int clip_ln(x1,y1,xc,yc,x2,y2)
  223. int x1,y1,x2,y2,*xc,*yc;
  224. {
  225.   int delx,dely,maxy;
  226.   long templ; 
  227.   maxy = max_lin() - 1;
  228.   *xc=x1; 
  229.   *yc=y1;
  230.   if ( y1 >= MINY && y1 <= maxy && x1 >= MINX && x1 <= MAXX) 
  231.      return(1);
  232.   dely=y1-y2;
  233.   delx=x1-x2;
  234.   if (y1 > maxy || y1 < MINY) {
  235.     if (y1 > maxy) {
  236.       if (y2 > maxy) return (0);
  237.       *yc=maxy;
  238.     } else {
  239.       if (y2 < MINY ) return(0);
  240.       *yc=MINY;
  241.     }
  242.     templ = (long)(*yc-y2)*(long)delx;
  243.     *xc=templ/dely+x2;
  244.     if (*xc >= MINX && *xc <= MAXX) {
  245.       return(1);
  246.     }
  247.   }
  248.   dely=*yc-y2;
  249.   delx=*xc-x2;
  250.   if (*xc > MAXX || *xc < MINX) {
  251.     if (*xc > MAXX) {
  252.       if (x2 > MAXX ) return(0);
  253.       *xc=MAXX;
  254.     }
  255.     else {
  256.       if (x2 < MINX ) return(0);
  257.       *xc=MINX;
  258.     }
  259.     templ = (long)(*xc-x2)*(long)dely;
  260.     *yc=templ/delx+y2;
  261.     if (*yc >= MINY && *yc <= maxy) {
  262.       return(1);
  263.     }
  264.   }
  265.   return(0);
  266. }
  267.  
  268. *********************end file CLIPLINE.C*************
  269. *********************begin file GRAFEX1.C************
  270.  
  271. #include <stdio.h>
  272. #include <math.h>
  273.  
  274. #define pi 3.1415926
  275.  
  276. main()
  277. {
  278.   int n, i, j, d;
  279.   unsigned color;
  280.   struct {
  281.     int x, y;
  282.   } vert[32];
  283.  
  284.   do {
  285.     printf("Enter number of vertices, 4 to 32: ");
  286.     scanf("%d", &n);
  287.     if ( n < 4 || n > 32 ) printf("Try again!\n");
  288.      } while( n < 4 || n > 32);
  289.  
  290.   setmod(16);     /*change ega to graphics mode*/
  291.   zsetup();       /*initialize drawing package...bios drawing stops working */
  292.  
  293. /* space n vertices equally on an ellipse that fits nicely on the screen */
  294.  
  295.   for (i=0; i<n; i++) {
  296.     vert[i].x = 319.49 + 200.*sin(2*pi/n*i);
  297.     vert[i].y = 174.49 - 160.*cos(2*pi/n*i);
  298.   }
  299.  
  300. /*
  301.  * draw the figure. the colors are selected so that points that are the
  302.  * same distance from each other on the ellipse have the same color.
  303.  */
  304.  
  305.   for (i=0; i<n; i++)
  306.     for (j=i+1; j<n; j++) {
  307.       d = j-i;
  308.       if (d > n/2) d = n - d;
  309.       color = (float)d/(n/2+1)*15 + 1;
  310.       zline(vert[i].x, vert[i].y, vert[j].x, vert[j].y, color);
  311.     }
  312.  
  313. /* wait... */
  314.  
  315.   curmod();    /*reset to allow bios to draw letters */
  316.   printf("Press any key...");
  317.   getch();
  318.  
  319. /* and clean up. */
  320.  
  321.   setmod(3);   /*back to text mode*/
  322. }
  323.  
  324. *******************end file GRAFEX1.C***************
  325. *******************begin file GRAFEX2.C*************
  326. char bigsym[5] = {60,102,195,102,60};
  327. char littlesym[5] = {0,24,60,24,0};
  328.  
  329. main()
  330. {
  331.       char *cptr;
  332.       int i, ix, iy, icount, icolor;
  333.       setmod(16);  /* set graphics mode*/
  334.       zsetup(); /*initialize graphics package*/
  335.       for (icount = 0 ; icount < 10000 ; icount++){
  336.             ix = rand()/51;
  337.             iy = rand()/93;
  338.             icolor = rand() & 7;
  339.  
  340. /*    symbol(ix,iy,iheight,icolor,symbol) draws a rectangular pattern 8 bits
  341.       wide and iheight bits high with upper left corner at ix,iy in color
  342.       *symbol. The patterns in this program are 
  343.                      bigsum               littlesym
  344.  
  345.                     ..****..              ........
  346.                     .**..**.              ...**...
  347.                     **....**              ..****..
  348.                     .**..**.              ...**...
  349.                     ..****..              ........
  350.      The result is a little spot with a bright center and a dim border.     */
  351.  
  352.                     
  353.             symbol(ix,iy,5,icolor+8,littlesym);
  354.             symbol(ix,iy,5,icolor,bigsym);
  355.          }
  356.       for(i = 0 ,cptr = "Hit any key to quit."; *cptr ;i++)
  357.           llettr(i << 3,0,*cptr++,15);
  358.  
  359.       while(!kbhit());
  360.       getch();
  361.       setmod(3);   /*go back to text mode*/
  362. }
  363.  
  364.  
  365. *******************end file GRAFEX2.c***************
  366. *******************begin file EGAGRA.DOC************
  367.              EGAGRA - Fast Graphics Routines for the EGA or VGA
  368.  
  369.       Egagra is as set of high speed graphics routines for the IBM EGA
  370. and VGA graphics systems. It runs on these in the BIOS modes 15, 16, and 18,
  371. which are 350X640 monochrome, 350X640 16 color and 480 X 640 16 color
  372. modes respectively. It provides routines for lines, filled rectangles,
  373. and open and filled ellipses, as well as two sizes of text and a routine
  374. to display text-like patterns. The routines (including the text ones) all
  375. draw over any previous pattern in a given area; the text ones do not result
  376. in a black rectangle around the text. The text drawing routines also allow
  377. text to be places to any arbitrary pixel position. A mask function allows
  378. writing to one or more bit planes while leaving others uneffected.
  379.       All of these routines are written in assembler in the calling sequence
  380. of Microsoft C, except for the ellipses and the clipped-line routine which
  381. are in C. A header file is provided so they can be used from Microsoft
  382. Fortran without changes. A set of demonstration programs in C and Fortran
  383. is included.
  384.       The first subroutine called when using this package is setmod(n),
  385. where n is the desired graphics mode. This simply calls the ROM BIOS to 
  386. set the desired mode; it still leaves the system in a text state so that
  387. the io routines of the language used are operational. The actual graphics
  388. calls (including text routines slettr, llettr and symbol) must be preceeded
  389. by a call to zsetup. After this call, language io to the console, such
  390. as printf or scanf in C or read and write to the console in Fortran, results
  391. in garbage. However, a call to curmod then re-enables language io. In 
  392. other words, between calls to zsetup and curmod you use these graphics
  393. routines, while after curmod calls you use the facilities of the programming
  394. language. (Of course, there is no effect on io to disk files or COM ports.)
  395. At the end of you program there must be a call to reset the BIOS mode to
  396. the original value, usually 2, 3, or 7. If this isn't done, DOS will write
  397. garbage to the screen, a problem which can be fixed from DOS by using
  398. MODE CO80, MODE BW80 or MODE MONO as desired. When using an EGA with the
  399. minimum memory on an IBM monochrome display in mode 15, use colors 0,
  400. 3, 12 and 15 only.   
  401.       All the drawing routines except zpoint clip the drawing to the
  402. horizontal confines of the screen. The rectangle and filled ellipse ones 
  403. clip vertically also. The rest simply draw on the portion of the screen
  404. buffer which is not mapped to the screen. A really long line or big ellipse
  405. will "wrap around". A routine called clipline draws a line clipped to the
  406. screen area.
  407.      Since these routines use the set/reset register of the ega, and the
  408. BIOS doesn't, if you ctrl-break out of one of them into DOS, screen
  409. garbage results. You should therefore put the zsetup/curmod calls closely
  410. around the actual drawing routines, and to be sure, trap the MS-DOS
  411. break interrupt and call a setmod(orig_mode) in the inteppupt routine.
  412.      The following description is for the C versions of the subroutines.
  413. The calling sequence for Fortran can be seen in the header file EGAFORT.H,
  414. which should be included in any Fortran routine using them. The routines
  415. will work in any memory model, but must be compiled separately for each.
  416. To make a library for a given model, perform the following steps:
  417.      1. Edit MACROS.AH to define the appropriate memory model. 
  418.      2. Use MASM on egagra.asm.
  419.      3. Compile ELLIPSE.C with the appropriate memory model switch, 
  420.         either /AS /AM /AC or /AL for small, medium, compact, or large.
  421.         ALSO use the /Fa switch. This will generate an ellipse.asm file.
  422.      4. Use MASM on ellipse.asm.
  423.      5. Repeat steps 4 & 5 on clipline.c.
  424.      6. Use LIB to combine the three .obj files into a library
  425.         egagrafs.lib, egagrafm.lib, egagrafc.lib, or egagrafl.lib as
  426.         appropriate.
  427. The contortions involved in making a .asm file out of ellipse and clipline
  428. and THEN assembling it are needed ONLY if you wish to use the library file
  429. with Fortran. This is done so that the C run-time library will not be
  430. automatically called, even if using Fortran. The ellipse routines don't
  431. need any run-time routines out of the C libraries, as all the necessary
  432. ones exist in Fortran. If you NEVER use Fortran, just compile ellipse.c
  433. directly with the correct memory-model switch. If you only have a Fortran
  434. compiler, you're out of luck with ellipses and clipped lines unless you 
  435. translate ellipse.c and clipline.c into Fortran (which is perfectly easy.)
  436.  
  437.                     Subroutine Descriptions
  438.  
  439.                     Utility Routines
  440.  
  441. setmod(i)
  442. int i;
  443.               This routine calls the BIOS to put the graphics adapter
  444.               into mode i.
  445.  
  446.  
  447. zsetup()
  448.               This routine initializes graphics drawing mode (see
  449.               text above). Zsetup is cancelled by curmod. The special
  450.               graphics drawing mode used by this package is slightly
  451.               different from the normal bios mode with the same resolution.
  452.  
  453. curmod()
  454.               This routine returns the adapter to normal bios drawing
  455.               mode, allowing BIOS calls to produce text.  
  456.  
  457. setpal(ipal,icol)
  458. int ipal, icol;
  459.               This routine changes the color produced by call a drawing
  460.               routine with color ipal to the physical color icol.
  461.               Ipal is a number from 0 to 15 whereas icol can vary from
  462.               0 to 63.
  463.  
  464. setpals(palete)
  465. char *palete;
  466.               The useage in a C program is
  467.                     char pal[17];
  468.                     setpals(pal);
  469.               where pal[0] to pal[15] are preset to the value desired
  470.               for the corresponding drawing color. pal[16] is the
  471.               border color; for ega mode it must be set to 0; the
  472.               other 16 values can range from 0 to 63. This call, unlike
  473.               setpal, sets all the 16 colors in one call.
  474.  
  475. setmask(mask)
  476. int mask;
  477.               This routine sets the bit map write enable mask. Since this
  478.               is rather cryptic, a bit of explanation is in order.
  479.               Consider a given pixel. Let's say it is presently in color
  480.               1. If we set mask to 15, which is the default state, and
  481.               write a point at that pixel with color 4, the pixel changes
  482.               to color 4. Set it back to 1. But now set mask to 4. Then
  483.               write color 4. The hardware then allows changes only to the
  484.               4's bit of the color; the 1's, 2's and 8's bits are write 
  485.               protected. Hence the color changes to 5. If we now set mask 
  486.               to 11 (1+2+8) and write a color 0, the color, now 5, changes 
  487.               to 4, since the 4's bit was protected. For an example
  488.               of the use of this, see the program "movers.c" and "moverm.c",
  489.               which generate exactly the same diaplay. The only difference
  490.               is that "movers.c" also uses page swapping.
  491.  
  492.  
  493. setdraw(i)
  494. int i;
  495.               This routine sends all following output to display page i.
  496.               Note that i must be 0 or 1. See the example program
  497.               "movers.c". A page need not be visible to be written to.
  498.               Apparently the VGA mode 18 has only one page.
  499.  
  500. setdisp(i)
  501. int i;
  502.               This routine causes page i (0 or 1) to be visible on the 
  503.               screen. See the example program "movers.c".
  504.  
  505.  
  506.  
  507.                     Text Routines
  508.  
  509. slettr(ix, iy, ichr, col)
  510. int ix, iy, ichr, col;
  511.  
  512. llettr(ix, iy, ichr, col)  
  513. int ix, iy, ichr, col;
  514.              
  515.              These two routines write text. They differ only in that slettr
  516.              draws using the 8 pixel high BIOS character set, while llettr
  517.              uses the ega 14 pixel high set. Ix and iy are the pixel
  518.              location of the upper left corner of the character box. They
  519.              need not be at a normal text cursor position; any value
  520.              -7 < ix < 647 and -14 < iy < (screen height + 13) is OK.
  521.              Ichr is the character; any value in the drawing set will 
  522.              work including the values less than 32 and the ones between
  523.              128 and 255. Character 219 is good for filling a whole
  524.              character box, such as simulating a background color. The
  525.              VGA 8x16 character set could be added by adapting the
  526.              initialization parts of slettr and llettr. I'm going to do
  527.              so when I get a PS/2, and call it xlettr. Adding a 9th
  528.              pixel row would be trickier.
  529.              
  530.  
  531. symbol(ix,iy,height,col,symb)
  532. int ix, iy, height, col;
  533. char *symb;
  534.              This routine operates just like the text routines except
  535.              that it draws a character of height height whose description
  536.              is contained in the array symb. Thus with height = 8
  537.              you can set an arbitrary patten of 256 pixels in an 8x8 
  538.              array. You can define your own character set, or use it
  539.              for icons.
  540.  
  541.                     Drawing Routines
  542.  
  543. zline(ix0, iy0, ix1, iy1, col)
  544. int ix0, iy0, ix1, iy1, col;
  545.              
  546.              This routine draws a line from ix0, iy0 to ix1, iy1 in
  547.              color col. The horizontal extent is restricted to the screen.
  548.  
  549. clipline(ix0, iy0, ix1, iy1, col)
  550. int ix0, iy0, ix1, iy1, col;
  551.              
  552.              This routine draws a line from ix0, iy0 to ix1, iy1 in
  553.              color col. It is restricted to the screen.
  554.  
  555. rectfill(ix0, iy0, ix1, iy1, col)
  556. int ix0, iy0, ix1, iy1, col;
  557.  
  558.              This routine draws a solid rectangle between diagonally
  559.              opposite corners ix0, iy0 and ix1, iy1 in color col.
  560.              Both horizontal and vertical extents are clipped to the screen.
  561.  
  562. ellipse(ix0, iy0, irx, iry, col)
  563. int ix0, iy0, irx, iry, col;
  564.  
  565. fillelip(ix0, iy0, irx, iry, col)
  566. int ix0, iy0, irx, iry, col;
  567.  
  568.              These routines draw ellipses centered at ix0, iy0 with
  569.              horizontal and vertical semi-axes irx and iry in color col.
  570.              Ellipse is open, fillelip is solid. The horizontal extent
  571.              is clipped to the screen. For a normal ega monitor,
  572.              iry = .8*irx generates a circle.
  573.  
  574. These routines were written by J. D. McDonald at the University of
  575. Illinois and are public domain.
  576.  
  577. ****************end file EGAGRA.DOC***************
  578. ****************begin file EGATEST.C**************
  579. char palete1[] = { 56, 9, 18, 27, 36, 45, 54, 63,
  580.              0, 1, 2, 3, 4, 5, 6, 7, 0};
  581. char palete2[] = { 0, 1, 2, 3, 4, 5, 6, 7,
  582.              56, 9, 18, 27, 36, 45, 54, 63, 0};
  583. unsigned char pattern[] = {204, 102, 51, 102, 204, 153, 51, 102,
  584.                            204, 102, 51, 102, 204, 153, 51, 102,
  585.                            204, 102, 51, 102, 204, 153, 51, 102 }; 
  586.  
  587. main()
  588. {
  589. char *cptr;
  590. int i, j, imode;
  591. int maxline = 350;
  592. do {
  593.     printf("Enter mode number, 16 for EGA, 16 or 18 for VGA");
  594.     scanf("%d",&imode); 
  595.  }  while( imode != 16 && imode != 18);
  596. if(imode == 18) maxline = 480;
  597. setmod(imode);
  598. zsetup();
  599. for(i = 0 ,cptr = "This should be large brown letters."; *cptr ;i++)
  600.        llettr(i << 3,0,*cptr++,6);
  601. for(i = 0 ,cptr = "At the upper left corner of the screen.";  *cptr ;i++)
  602.        llettr(i << 3,14,*cptr++,6);
  603. for(i = 0 ,cptr = "\003 \033There should be half a green heart (\003) at"; *cptr ;i++)
  604.        llettr((i << 3)-3,maxline/2-7,*cptr++,2);
  605. for(i = 0 ,cptr = "   the center of each edge of the screen."; *cptr ;i++)
  606.        llettr((i << 3)-3,maxline/2+7,*cptr++,2);
  607. llettr(316,-7,3,2);
  608. llettr(316,maxline-7,3,2);
  609. llettr(636,maxline/2-7,3,2);
  610. for(i = 0 ,cptr = "This should be small bright blue letters."; *cptr ;i++)
  611.        slettr(i << 3,30,*cptr++,9);
  612. ellipse(500,100,50,90,3);
  613. fillelip(500,100,20,20,4);
  614. for(i = 0 ,cptr = "Small filled red ellipse"; *cptr ;i++)
  615.        llettr(400+(i << 3),196,*cptr++,4);
  616. for(i = 0 ,cptr = "Large open cyan ellipse"; *cptr ;i++)
  617.        llettr(400+(i << 3),210,*cptr++,3);
  618. rectfill(100,250,539,300,7);
  619. zline(99,249,540,249,13);
  620. zline(99,249,99,301,13);
  621. zline(99,301,540,301,13);
  622. zline(540,249,540,301,13);
  623. zline(99,249,540,301,13);
  624. zline(99,301,540,249,13);
  625. for(i = 0 ,cptr = "Gray rectangle with violet border and cross."; *cptr ;i++)
  626.        llettr(142+(i << 3),310,*cptr++,13);
  627. for(i = 0 ,cptr = "Hit any key."; *cptr ;i++)
  628.        llettr(40+(i << 3),100,*cptr++,7);
  629. for(i = 0; i < 245; i += 8)symbol(i,50,24,6,pattern);
  630. for(i = 0 ,cptr = " Yellow text on brown pattern."; *cptr ;i++)
  631.        llettr((i << 3),55,*cptr++,14);
  632. for(i = 0 ,cptr = "This will appear only in mode 18"; *cptr ;i++)
  633.        llettr((i << 3),390,*cptr++,7);
  634. zline(0,412,256,412,7);
  635. while(!kbhit());
  636. setpals(palete1);
  637. getch();
  638. for(i = 0 ,cptr = "Dark and light colors should be reversed."; *cptr ;i++)
  639.        llettr(40+(i << 3),196,*cptr++,7);
  640. while(!kbhit());
  641. getch();
  642. for(i = 0 ,cptr = "The red ellipse should now be green."; *cptr ;i++)
  643.        llettr(40+(i << 3),210,*cptr++,7);
  644. rectfill(50,480,100,600,7);
  645. setdraw(1);
  646. for(i = 0 ,cptr = "This is the second video page."; *cptr ;i++)
  647.        llettr(150+(i << 3),200,*cptr++,7);
  648. for(i = 0 ,cptr = "Three lines of text, and nothing else,should appear."
  649.                 ; *cptr ;i++)llettr(150+(i << 3),215,*cptr++,7);
  650. for(i = 0 ,cptr = "Hit any key."; *cptr ;i++)
  651.        llettr(150+(i << 3),230,*cptr++,7);
  652. setpal(4,18);
  653. while(!kbhit());
  654. getch();
  655. setpals(palete2);
  656. setdisp(1);
  657. while(!kbhit());
  658. getch();
  659. setmod(3);
  660.  
  661. *****************end file EGATEST.C*****************
  662. *****************begin file MOVERS.C****************
  663. #include <math.h>
  664. #define PI128 3.141585/128.
  665.     char quit_string[] = "Hit any key to quit.";
  666.     char palete1[17] = { 0, 1, 58, 58, 62, 62, 62, 62, 4,
  667.                            7, 4, 4,  4,  4,  4,  4, 0 } ;
  668. /*This program draws a moving ball with animation done using the page
  669.   swapping method. It is speed limited by the necessity to swap only
  670.   during vertical retrace.                                            */
  671.  
  672.  
  673. double xs[256], ys[256];
  674. main()
  675. {
  676.     int  x1, y1, x2, y2, i, icol, j;
  677.     double x, y;
  678.  
  679.     setmod(16);
  680.     zsetup();
  681.     setpals(palete1);    
  682.     setmask(15);
  683.     setdraw(0);
  684.     rectfill(0,0,639,349,0);
  685.     for (i = 0; i < 8; i++) {
  686.       rectfill(i*80, 0, i*80+19,349,1);
  687.       rectfill(i*80+40, 0 , i*80+59, 349,8);
  688.     }
  689.     for (i = 0; i < 20; i++) llettr(i*9, 16, quit_string[i], 9);
  690.     setdraw(1);
  691.     rectfill(0,0,639,349,0);
  692.     for (i = 0; i < 8; i++) {
  693.       rectfill(i*80, 0, i*80+19,349,1);
  694.       rectfill(i*80+40, 0 , i*80+59, 349,8);
  695.     }
  696.     for (i = 0; i < 20; i++) llettr(i*9, 16, quit_string[i], 9);
  697.       setmask(6);
  698.     x2=320;
  699.     y2=175;
  700.     for (i = 0; i < 256; i++) {
  701.         xs[i] = 320.-300.*sin(PI128*i);
  702.         ys[i] = 175.+100.*cos(PI128*i);
  703.     }
  704.     for (i = 0; !kbhit() ; i = (i+1) & 255 ) {
  705.       if( i & 1) {
  706.           setdisp(0);
  707.           setdraw(1);
  708.       } else {
  709.           setdisp(1);
  710.           setdraw(0);
  711.       }    
  712.       while( !( inp(0x3da) & 8));      
  713.         x= xs[i];
  714.         y= ys[i];
  715.         rectfill(x2-10,y2-9,x2+10,y2+9,0);
  716.           x2 = x1;
  717.           y2 = y1;
  718.           x1 = x;
  719.           y1 = y;
  720.           if(y1 > 175 && x1 >= 50 && x1 <= 130) icol = 2;
  721.               else icol = 4;
  722.           fillelip(x1,y1,10,8,icol);
  723.     }
  724.     setdisp(0);
  725.     setmod(3);
  726.  }
  727.  
  728.  
  729. **************end file MOVERS.C***************
  730. **************begin file MOVERM.C*************
  731. #include <math.h>
  732. #define PI128 3.141585/128.
  733.     char quit_string[] = "Hit any key to quit.";
  734.     char palete1[17] = { 0, 1, 0, 1, 62, 62, 62, 62, 4,
  735.                            7, 4, 4,  4,  4,  4,  4, 0 } ;
  736.     char palete2[17] = { 0, 1, 62, 62, 0, 1, 62, 62, 4,
  737.                            7, 4, 4,  4,  4,  4,  4, 0 } ;
  738.     char palete3[17] = { 0, 1, 0, 1, 58, 58, 58, 58, 4,
  739.                            7, 4, 4,  4,  4,  4,  4, 0 } ;
  740.     char palete4[17] = { 0, 1, 58, 58, 0, 1, 58, 58, 4,
  741.                            7, 4, 4,  4,  4,  4,  4, 0 } ;
  742. /*This program draws a moving ball with animation done using the palete
  743.   swapping method. It is speed limited by the necessity to swap only
  744.   during vertical retrace.                                            */
  745.  
  746. double xs[256], ys[256];
  747.  
  748. main()
  749. {
  750.     int  x1, y1, x2, y2, i;
  751.     double x, y;
  752.  
  753.     setmod(16);
  754.     zsetup();
  755.     setpals(palete1);    
  756.     setmask(15);
  757.     for (i = 0; i < 8; i++) {
  758.       rectfill(i*80, 0, i*80+19,349,1);
  759.       rectfill(i*80+40, 0 , i*80+59, 349,8);
  760.     }
  761.     for (i = 0; i < 256; i++ ) {
  762.       xs[i] = 320.-300.*sin(PI128*i);
  763.       ys[i] = 175.+100.*cos(PI128*i);
  764.     }
  765.     x2=320;
  766.     y2=175;
  767.     for (i = 0; i < 20; i++) llettr(i*9, 16, quit_string[i], 9);
  768.     for (i = 0; !kbhit() ; i = (i+1) & 255 ) {
  769.       x= xs[i];
  770.       y= ys[i];
  771.       if( i & 1) {
  772.           setmask(4);
  773.           rectfill(x2-10,y2-9,x2+10,y2+9,0);
  774.           x2 = x1;
  775.           y2 = y1;
  776.           x1 = x;
  777.           y1 = y;
  778.           fillelip(x1,y1,10,8,4);
  779.           if(y1 > 175 && x1 >= 50 && x1 <= 130) setpals(palete3);
  780.               else setpals(palete1);
  781.       } else {
  782.           setmask(2);
  783.           rectfill(x2-10,y2-9,x2+10,y2+9,0);
  784.           x2 = x1;
  785.           y2 = y1;
  786.           x1 = x;
  787.           y1 = y;
  788.           fillelip(x1,y1,10,8,2);
  789.           if(y1 > 175 && x1 >= 50 && x1 <= 130) setpals(palete4);
  790.               else setpals(palete2);
  791.       }  
  792.     }
  793.     setmod(3);
  794.  }
  795.  
  796.  
  797.  
  798. ***************end file MOVERM.C**************
  799. ***************begin file INTEST.ASM**********
  800. _TEXT    SEGMENT  BYTE PUBLIC 'CODE'
  801. _TEXT    ENDS
  802. _DATA    SEGMENT  WORD PUBLIC 'DATA'
  803. _DATA    ENDS
  804. CONST    SEGMENT  WORD PUBLIC 'CONST'
  805.  
  806. CONST    ENDS
  807. _BSS    SEGMENT  WORD PUBLIC 'BSS'
  808.  
  809. _BSS    ENDS
  810. DGROUP    GROUP    CONST, _BSS, _DATA
  811.     ASSUME  CS: _TEXT, DS: DGROUP, SS: DGROUP, ES:  DGROUP
  812. _TEXT      SEGMENT
  813.  
  814.  
  815. ;intest.asm
  816. ;if there is no input returns 0
  817. ;if there is input it returns 255
  818.  
  819. intest          PROC      FAR
  820. PUBLIC           intest
  821.           mov       ah,0bh
  822.           int       21h
  823.           xor       ah,ah
  824.           ret
  825. intest   endp
  826.  
  827.  
  828. _TEXT    ENDS
  829. END
  830.  
  831.  
  832. **************end file INTEST.ASM***************
  833. **************begin file SLUGS.FOR**************
  834. $storage:2
  835. $include:'egafort.h'
  836.         IMPLICIT INTEGER*2 (I-N)
  837.         CHARACTER*10 IZC
  838.     DIMENSION JCOL(11)
  839.         WRITE(*,*)' Demo program for EGA.'
  840.         WRITE(*,*)' To begin hit return'
  841.         READ(*,1000)IZC
  842. 1000    FORMAT(A10)
  843.         IDRAW=0
  844.         CALL SETMOD(16)
  845.         CALL ZSETUP
  846. 1       DO 2 I=1,11
  847. 2           JCOL(I)=0
  848.         CALL RECTFILL(0,0,639,349,0)
  849.         DO 5  I=1,11
  850. 3        ICOL=RAN()*25.+1.1
  851.         DO 4 J=1,11
  852. 4            IF(ICOL.EQ.JCOL(J))GOTO 3
  853.         JCOL(I)=ICOL
  854.             IF(RAN().GT..6)THEN
  855.               CALL BLOT(ICOL)
  856.         ELSE
  857.                  CALL SLUG(ICOL)
  858.             ENDIF
  859. 5    CONTINUE
  860.         CALL SLEEP(4)
  861.         GOTO 1
  862.     END
  863.     SUBROUTINE BLOT(ICOL)
  864.     IMPLICIT INTEGER*2 (I-N)
  865.         IXCEN=639.*RAN()
  866.     IYCEN=349.*RAN()
  867.     DO 1 I=1,25
  868.           IRAD=4.+12.*RAN()
  869.         RADIUS=70.*RAN()
  870.         ANG=6.28*RAN()
  871.         IX=RADIUS*SIN(ANG)
  872.         IY=.8*RADIUS*COS(ANG)
  873.         CALL FCIRC(IXCEN+IX,IYCEN+IY,IRAD,ICOL)
  874. 1    CONTINUE
  875.     RETURN
  876.     END
  877.     SUBROUTINE SLUG(ICOL)
  878.         IMPLICIT INTEGER*2 (I-N)
  879.     DIMENSION WIDTH(12),SINTAB(0:32)
  880.         DATA IFIRST/0/
  881.         IF(IFIRST.EQ.0)THEN
  882.             DO 1 I=0,32
  883. 1           SINTAB(I)=SIN(3.1415926*I/16.)
  884.             IFIRST = 1
  885.         ENDIF
  886.     DO 2 I=1,12
  887. 2    WIDTH(I)=5.05*RAN()
  888.     IX=320.+160.*RAN()
  889.     IY=175.+90.*RAN()
  890.     DTHET=6.28*RAN()
  891.     DR=1.5+2.5*RAN()
  892.     DX=DR*SIN(DTHET)
  893.     DY=DR*COS(DTHET)
  894.     DIST=0.
  895.     DIST2=0.
  896.     DO 5 I=1,60
  897.     DTHET=1.6*RAN()
  898.     IF(DTHET.LT..8)DTHET=DTHET-1.6
  899.     CCOS=.05*COS(DTHET)
  900.     SSIN=.05*SIN(DTHET)
  901.     DDX=DX*CCOS+DY*SSIN-.05*DX
  902.     DDY=DY*CCOS-DX*SSIN-.05*DY
  903.     DO 4 J=1,20
  904.          DX=DX+DDX
  905.         DY=DY+DDY
  906.         IX2=IX+DX
  907.         IY2=IY+DY
  908.         DIST2=DIST2+DX
  909.         DIST=DIST+DR
  910.         IF(DIST.GE.1.3)THEN
  911.               DIST=0.
  912.             WD=0.
  913.             DO 3 LL=1,6
  914.                     MSIN = IAND(IFIX(DIST2*WIDTH(LL+6)),31)
  915. 3                WD=WD+WIDTH(LL)*SINTAB(MSIN)
  916.             IWD=ABS(WD)+4.
  917.             CALL FCIRC(IX,IY,IWD,ICOL)
  918.             ENDIF
  919.         IX=IX2
  920.         IY=IY2
  921.         IF(IX.GT.690)IX=IX-750
  922.         IF(IY.GT.400)IY=IY-450
  923.         IF(IX.LT.-50)IX=IX+750
  924.         IF(IY.LT.-50)IY=IY+450
  925. 4        CONTINUE
  926.         IF(INTEST().NE.0)THEN
  927.             CALL SETMOD(3)
  928.             STOP
  929.         ENDIF
  930. 5    CONTINUE
  931.     RETURN
  932.     END
  933.         FUNCTION RAN()
  934.         IMPLICIT INTEGER*4 (L)
  935.         IMPLICIT INTEGER*2 (M-N)
  936.         DIMENSION M(2)
  937.         EQUIVALENCE (M(1),L2)
  938.         DATA IFIRST/0/
  939.         IF(IFIRST.EQ.0)THEN
  940.             CALL GETTIM(ID1,ID2,ITT2,ITT1)
  941.             L1=ITT1+100*ITT2
  942.             IF(MOD(L1,2).EQ.0)L1=L1+1
  943.             IFIRST = 1
  944.         ENDIF
  945.         L2=L1
  946.         M(2)=0
  947.         L2=L2*259
  948.         M(2)=0
  949.         RAN=L2/65536.
  950.         L1=L2
  951.         RETURN
  952.         END
  953.         SUBROUTINE FCIRC(IX,IY,ISIZ,ICOL)
  954.         IMPLICIT INTEGER*2 (I-N)
  955.         DIMENSION ICOLSO(46),ICOLSI(46)
  956.         DATA ICOLSO/1,1,1,1,1,1,1,1,
  957.      1              2,2,2,2,3,3,
  958.      2              4,4,4,4,4,4,4,
  959.      3              5,5,5,6,6,6,6,6,6,
  960.      4              7,8,8,8,8,
  961.      5              9,9,9,9,9,
  962.      6              12,12,12,12,12,13/
  963.         DATA ICOLSI/2,6,7,9,10,12,13,14,
  964.      1              1,10,14,15,12,14,
  965.      2              2,7,9,10,12,13,14,
  966.      3              2,7,13,2,3,7,10,14,15,
  967.      4              14,9,11,12,13,
  968.      5              2,7,10,13,14,
  969.      6              2,7,9,10,15,15/
  970.         ISIZ2 = (ISIZ*8)/10
  971.         CALL FILLELIP(IX,IY,ISIZ,ISIZ2,ICOLSI(ICOL))
  972.         CALL ELLIPSE(IX,IY,ISIZ,ISIZ2,ICOLSO(ICOL))
  973.         RETURN
  974.         END
  975.         subroutine sleep(isleep)
  976.         implicit integer*2 (a-z)
  977.         call gettim(ihr,imin,isec,itic)
  978.         isec = isec+isleep
  979.         if(isec.gt.59)then
  980.             isec = isec-60
  981.             imin = imin+1
  982.         endif
  983.         if(imin.gt.59)then
  984.             imin = imin-60
  985.             ihr = ihr+1
  986.         endif
  987.         if(ihr.eq.23)then
  988.             ihr = 0
  989.         endif
  990. 1       call gettim(ihr1,imin1,isec1,itic)
  991.         if(ihr1.ne.ihr.or.imin.ne.imin1.or.isec.ne.isec1)goto 1
  992.         return
  993.         end
  994.  
  995. ****************end file SLUGS.FOR*****************
  996.